#include "Servidor.h"
#include "HiloCliente.h"
#include "HiloSimulacion.h"
#include "../parser/InicializadorConfiguracion.h"
#include "../parser/CreadorCanvas.h"

Servidor::Servidor(int puerto, string mision, string objetivo) {
	this->puerto = puerto;
	this->misionActual = mision;
	this->objetivoActual = objetivo;
	this->idClienteActual = 1;
	this->cantidadJugadores = 1;
	this->configuracionNivel = new ConfiguracionNivel(
			objetivo);
	this->cantidadMaxJugadores = this->configuracionNivel->getCantidadJugadores();
	this->cantidadPlay = 0;
	this->hiloSimulacion = NULL;
	this->persistencia = NULL;
	this->creadorCanvas = NULL;
	this->juegoActivo = true;
	mensajeMision = "VACIO!";
}

Servidor::~Servidor() {
	sock.cerrar();
}

int Servidor::iniciar() {
	cout << "Inicio el servidor con puerto: " << puerto << endl;
	if (sock.bindear(puerto) != 0) {
		cout << "No se puede crear el servidor en el puerto solicitado:  "
				<< puerto << endl;
		return 1;
	}
	iniciarObjetivo();
	iniciarEscenarioMision();
	while (true) {
		cout << "Esperando conexion cliente " << endl;
		Socket* socketCliente = sock.aceptarConexion();
		if(!juegoActivo) break;
		cout << "Cliente recibido " << endl;

		HiloCliente* hiloCliente = new HiloCliente(socketCliente, this, this->objetivoActual);
		cout << "nuevo cliente " << endl;
		hiloCliente->iniciar();
		cout << "cliente iniciairrr " << endl;
	}
	return 0;
}

void Servidor::iniciarObjetivo() {
	creadorNivel = new CreadorNiveles();
	nivel = creadorNivel->obtenerNivel(this->configuracionNivel->getNivel());

}
int Servidor::getIdActual() {
	if(jugadoresConectados.size() == cantidadMaxJugadores){
		return -1;
	}
	else{
		int resultado = 0;
		mutexJugadores.lockear();
		for(unsigned int i = 1; i <= cantidadMaxJugadores; i++){
			if (jugadoresConectados.count(i) == 0){
				resultado = i;
				jugadoresConectados.insert(i);
				break;
			}
		}
		cantidadJugadores++;
		mutexJugadores.deslockear();
		return resultado;
	}
}

string Servidor::obtenerMisionActual() {
	return this->misionActual;
}

void Servidor::iniciarSimulacion() {
	persistencia->setCanvas(this->canvas);
	persistencia->escribirArchivo("temporali.yaml");
	this->hiloSimulacion = new HiloSimulacion(this->ventana, &mutexCanvas,
			nivel,&sock,&juegoActivo,&mensajeMision);
	this->hiloSimulacion->iniciar();
}

void Servidor::detenerSimulacion() {
	cout << "crearrr canvas priemro " << endl;

	this->hiloSimulacion->detener();
	Canvas* canvasAntiguo = this->canvas;
	cout << "crearrr canvas " << endl;
	this->canvas = creadorCanvas->obtenerCanvas("temporali.yaml");
	cout << "crearrr canvas 1 " << endl;
	this->canvas->dibujarElementosServer(ventana->getRenderer());
	cout << "crearrr canvas 22 " << endl;
	ventana->setCanvas(this->canvas);
	persistencia->setCanvas(this->canvas);
	cout << "crearrr canvas  33 " << endl;
	cout << "crearrr canvas 55 " << endl;
	delete canvasAntiguo;
	cout << "crearrr canvas 66 " << endl;
}
string Servidor::obtenerObjetivoActual(){
	return this->objetivoActual;
}

void Servidor::iniciarEscenarioMision() {
	builder = BuilderElementos::obtenerInstancia();
	InicializadorConfiguracion InicializadorConfiguracion;
	InicializadorConfiguracion.parsearConfiguracion("configuracion.yaml",
			builder);
	CreadorCanvas* creadorCanvas = new CreadorCanvas(builder);
	this->canvas = creadorCanvas->obtenerCanvas(this->misionActual);
	double ancho = 640;
	double alto = 569;
	double x = 100;
	double y = 100;
	this->ventana = new Ventana(x, y, ancho, alto, canvas,
			builder->obtenerListaElementos());
	this->ventana->inicializarServer();
	this->ventana->getMenu()->setClickPlayStop(false);
	this->canvas->dibujarElementosServer(ventana->getRenderer());
	this->persistencia = new PersistenciaCanvas(canvas);
	this->creadorCanvas = new CreadorCanvas(builder);
}

Canvas* Servidor::getCanvas() {
	return this->canvas;
}
Ventana* Servidor::getVentana() {
	return this->ventana;
}
BuilderElementos* Servidor::getBuilderElementos() {
	return this->builder;
}

int Servidor::getCantidadPlay() {
	return this->cantidadPlay;
}

void Servidor::setCantidadPlay(int cant) {
	this->cantidadPlay = cant;
}

void Servidor::setCantidadJugadores(int cant){
	this->cantidadJugadores = cant;
}

int Servidor::getCantidadJugadores() {
	return this->cantidadJugadores;
}

int Servidor::getCantidadMaximaJugadores(){
	return this->cantidadMaxJugadores;
}
